﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using Silent.MDB.Common.Services;
using Silent.MDB.Server.Model.Contexts;
using Silent.MDB.Server.Model.Repositories;
using Silent.MDB.Server.Model.Services;
using UriBuilder = Silent.WCF.Base.Common.UriBuilder;

namespace Silent.MDB.Server.Model
{
    public static class ApplicationCore
    {
        public const string SQL_SERVER_DATABASE = "SqlServerDatabase";
        public const string SQL_COMPACT_DATABASE = "SqlCompactDatabase";
        public const string MYSQL_DATABASE = "MySqlDatabase";
        public const string MYSQL_DATABASE_FPMI = "MySqlDatabaseFPMI";

        public static ServiceManager ServiceManager { get; private set; }
        public static List<string> AvailableLocations { get; private set; }
        public static Dictionary<string, IRepositoryManager> RepositoryManagers { get; private set; }

        private static void InitializeDatabase<TContext>(DefaultDbContext databaseContext, IRepositoryManager repositoryManager, string location)
            where TContext : DbContext
        {
            try
            {
                Console.WriteLine("initializing {0} context...", location);
                AvailableLocations.Add(location);
                Console.WriteLine("initializing {0} repositories...", location);
                InitializeRepositoryManager(repositoryManager, databaseContext);
                Database.SetInitializer(new CreateDatabaseIfNotExists<TContext>());
                databaseContext.Configuration.LazyLoadingEnabled = false;
                databaseContext.Configuration.ProxyCreationEnabled = false;
                databaseContext.Database.CreateIfNotExists();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        private static void InitializeRepositoryManager(IRepositoryManager repositoryManager, IDataContext dataContext)
        {
            RepositoryManagers.Add(repositoryManager.Name, repositoryManager);
            repositoryManager.AddRepository(new RootObjectsRepository(dataContext));
            repositoryManager.AddRepository(new FoldersRepository(dataContext));
            repositoryManager.AddRepository(new StudentsRepository(dataContext));
            repositoryManager.AddRepository(new TeachersRepository(dataContext));
            repositoryManager.AddRepository(new DepartmentRepository(dataContext));
            repositoryManager.AddRepository(new CathedraRepository(dataContext));
            repositoryManager.AddRepository(new FacultyRepository(dataContext));
        }
        public static void Initialize()
        {
            AvailableLocations = new List<string>();
            RepositoryManagers = new Dictionary<string, IRepositoryManager>();

            InitializeDatabase<SqlCompactContext>(new SqlCompactContext(SQL_COMPACT_DATABASE), new RepositoryManagerDefault(SQL_COMPACT_DATABASE), SQL_COMPACT_DATABASE);
            InitializeDatabase<MySqlContext>(new MySqlContext(MYSQL_DATABASE), new RepositoryManagerDefault(MYSQL_DATABASE), MYSQL_DATABASE);
            InitializeDatabase<MySqlContext>(new MySqlContext(MYSQL_DATABASE_FPMI), new RepositoryManagerDefault(MYSQL_DATABASE_FPMI), MYSQL_DATABASE_FPMI);
        }
        public static void StartService()
        {
            Console.WriteLine("creating service host...");
            ServiceManager = new ServiceManager();
            ServiceManager.Initialize();

            Console.WriteLine("initializing service host...");
            var uri = new UriBuilder().GetAddress("localhost", 5000);
            var host = new ServiceHostBuilder().Build(ServiceManager, uri);
            ServiceManager.Host = host;
            ServiceManager.Host.Open();
        }
    }
}
